using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;
using Services;
using MainGame;
using MainGame.Menu;
using MainGame.GameSound;

namespace MainGame.GamePlay
{
  //using System.Text;

  /// <summary>
  /// Disegna la UI del gioco e gestisce il click sul bottone Next Turn
  /// </summary>
  public abstract class UIRenderer : IntroRenderer
  {
    Texture2D clock, glass, barr, noteOn, noteOff, menuTexture, showTakes, play;
    private Vector2 clockPosition, clockEndPosition;
    //Button HelpButton, MenuButton, MusicButton, NextSongButton;
    Button MenuButton;
    private bool musicON = true;
    //private Rectangle songRectangle;
    public bool Outro;
    private Rectangle showLastTakeRect;
    private Rectangle[] turnStartBtns;

    //public float elapsedTime { get; set; }
    public UIRenderer(Game game)
      : base(game)
    {
      //UpdateOrder = (int)ComponentOrders.UI;

      //game.Services.AddService(typeof(IUIRenderer), this);
    }

    protected override void Dispose(bool disposing)
    {
      //Game.Services.RemoveService(typeof(IUIRenderer));
      base.Dispose(disposing);
    }


    protected override void OnEnabledChanged(object sender, EventArgs args)
    {
      if (MenuButton.color == Color.Red)
        MenuButton.color = Color.White;
      else
        MenuButton.color = Color.Red;
      base.OnEnabledChanged(sender, args);
    }

    public override void Initialize()
    {
      base.Initialize();

      //OnMenuPause += new GamePlay.OnMenuPause(OpenMenu);
      // Bottoni
      MenuButton = new Button(Game, @"Images//Menu//PauseButton", new Rectangle(715, 5, 80, 55), Color.White, "small_font", "", Color.Yellow);

      showLastTakeRect = new Rectangle(10, 5, 80, 60);
    }

    private void OpenMenu()
    {
      //TouchPanel.EnabledGestures = GestureType.None;
      //renderState = RenderState.PauseMenu;
    }

    protected override void LoadContent()
    {
      showTakes = Game.Content.Load<Texture2D>(@"Images//Game//ShowTake");
      menuTexture = Game.Content.Load<Texture2D>(@"Images//Menu//PauseButton");
      play = Game.Content.Load<Texture2D>(@"Images//Game//Play");

      base.LoadContent();

      playerAreas[0].takeCoords = new Vector2[5];
      playerAreas[0].takeCoords[0] = new Vector2(550, gameState.Players[0].Position.Y + 50);
      playerAreas[0].takeCoords[1] = new Vector2(480, gameState.Players[0].Position.Y);
      playerAreas[0].takeCoords[2] = new Vector2(410, gameState.Players[0].Position.Y);
      playerAreas[0].takeCoords[3] = new Vector2(340, gameState.Players[0].Position.Y);
      playerAreas[0].takeCoords[4] = new Vector2(270, gameState.Players[0].Position.Y);

      playerAreas[1].takeCoords = new Vector2[5];
      playerAreas[1].takeCoords[0] = new Vector2(230, gameState.Players[1].Position.Y - 50);
      playerAreas[1].takeCoords[1] = new Vector2(300, gameState.Players[1].Position.Y);
      playerAreas[1].takeCoords[2] = new Vector2(370, gameState.Players[1].Position.Y);
      playerAreas[1].takeCoords[3] = new Vector2(440, gameState.Players[1].Position.Y);
      playerAreas[1].takeCoords[4] = new Vector2(530, gameState.Players[1].Position.Y);

      if (gameState.Players.Count > 2)
      {
        playerAreas[1].takeCoords[0] = new Vector2(gameState.Players[1].Position.X + 50, 120);
        playerAreas[1].takeCoords[1] = new Vector2(gameState.Players[1].Position.X, 200);
        playerAreas[1].takeCoords[2] = new Vector2(gameState.Players[1].Position.X, 270);
        playerAreas[1].takeCoords[3] = new Vector2(gameState.Players[1].Position.X, 340);
        playerAreas[1].takeCoords[4] = new Vector2(gameState.Players[1].Position.X, 410);

        playerAreas[2].takeCoords = new Vector2[5];
        playerAreas[2].takeCoords[0] = new Vector2(230, gameState.Players[2].Position.Y - 50);
        playerAreas[2].takeCoords[1] = new Vector2(300, gameState.Players[2].Position.Y);
        playerAreas[2].takeCoords[2] = new Vector2(370, gameState.Players[2].Position.Y);
        playerAreas[2].takeCoords[3] = new Vector2(440, gameState.Players[2].Position.Y);
        playerAreas[2].takeCoords[4] = new Vector2(530, gameState.Players[2].Position.Y);
      }

      if (gameState.Players.Count > 3)
      {
        playerAreas[3].takeCoords = new Vector2[5];
        playerAreas[3].takeCoords[0] = new Vector2(gameState.Players[3].Position.X - 50, 380);
        playerAreas[3].takeCoords[1] = new Vector2(gameState.Players[3].Position.X, 300);
        playerAreas[3].takeCoords[2] = new Vector2(gameState.Players[3].Position.X, 220);
        playerAreas[3].takeCoords[3] = new Vector2(gameState.Players[3].Position.X, 160);
        playerAreas[3].takeCoords[4] = new Vector2(gameState.Players[3].Position.X, 90);
      }

      // Prepare turn start buttons
      turnStartBtns = new Rectangle[4];
      for (int i = 0; i < gameState.Players.Count; i++)
      {
        turnStartBtns[i] = new Rectangle((int)playerAreas[i].blockPosition.X, (int)playerAreas[i].blockPosition.Y, play.Bounds.Width, play.Bounds.Height);

        switch (i)
        {
          case 0:
            turnStartBtns[i].Offset(0, -20);
            break;
          case 1:
            if (gameState.Players.Count == 2)
              turnStartBtns[i].Offset(0, 20);
            else
              turnStartBtns[i].Offset(20, 0);
            break;
          case 2:
            turnStartBtns[i].Offset(0, 20);
            break;
          case 3:
            turnStartBtns[i].Offset(-20, 0);
            break;
        }
      }
    }

    public override void Update(GameTime gameTime)
    {
      if (renderState != RenderState.Intro)
      {
        // Input: back button pressed
        if (((Game1)Game).IsBackButtonPressed())
        {
          //MenuButton.color = Color.Red;
          if (OnMenuPause != null)
            OnMenuPause();
        }

        // Ripristina colore Bottoni
        //HelpButton.color = XNAColor.Blue;
        //MenuButton.color = XNAColor.Blue;
      }

      if (renderState == RenderState.Intro)
      {
        // Input: back button pressed
        if (((Game1)Game).IsBackButtonPressed())
        {
          //MenuButton.color = Color.Red;
          if (OnMatchExit != null)
            OnMatchExit();
        }
      }

      foreach (var g in cachedGestures)
      {
        switch (g.GestureType)
        {
          case GestureType.Tap:
            // Check if menu button was tapped
            if (MenuButton.IsInBounds(g.Position.ToPoint(screen_transform)) && OnMenuPause != null)
            {
              //MenuButton.color = Color.Red;
              //renderState = RenderState.PauseMenu;
              if (OnMenuPause != null)
                OnMenuPause();
            }
            break;
        }
      }

      base.Update(gameTime);
    }

    public override void UpdateUI(GameTime gameTime)
    {
      foreach (var g in cachedGestures)
      {
        switch (g.GestureType)
        {
          case GestureType.Tap:
            if (renderState == RenderState.Input && gameState.Players[gameState.CurrentPlayerIndex].AIType == AIType.Human)
            {
              // Check if the button to show last take was tapped
              if (showLastTakeRect.Contains(g.Position.ToPoint(screen_transform)))
              {
                // Change state and start animations
                renderState = RenderState.ShowLastTake;
                for (int i = 0; i < gameState.Players.Count; i++)
                {
                  var player = gameState.Players[i];
                  if (player.Takes.Any())
                  {
                    var take = player.Takes.Last();
                    float firstDepth = 0.8f;

                    // Set the initial positions of the cards to show
                    for (int j = 0; j < take.Cards.Count; j++)
                    {
                      var card = take.Cards[j];
                      if (j == (take.Cards.Count - 1))
                      {
                        // This is the card the player used to take
                        card.CoordPosition = playerAreas[i].takeCoords[0];
                        card.IsBeingDragged = true;
                        card.Depth = firstDepth + 0.06f;
                      }
                      else
                      {
                        // The other cards in the take
                        card.CoordPosition = playerAreas[i].takeCoords[j + 1];
                        card.Depth = firstDepth - (j * 0.01f);
                      }
                      card.Width = (int)(0.9f * CARD_WIDTH);
                      card.Height = (int)(0.9f * CARD_HEIGHT);
                      card.Rotation = playerAreas[gameState.CurrentPlayerIndex].cardsRotation;
                      gameState.Animations.Add(new CardAnimation() { Card = card, AnimationFinished = false, AnimationType = GamePlay.AnimationType.MoveByAmount, Amount = 330, PlayerIndex = i });
                    }

                    gameState.MossaFatta = true;

                  }
                }
              }
            }
            break;
        }
      }




      // Controlla se il pulsante deve avere l'effetto "premuto"
      if (MenuButton.touched)
      {
        //// Salva il colore originale
        //if (MenuButton.color != MenuButton.TouchColor)
        //  SavedColor = MenuButton.color;
        ////Controlla se il pulsante ha un colore specifico per l'effetto "premuto"
        //if (MenuButton.TouchColor != new Color(0, 0, 0, 0))
        //  touchedColor = MenuButton.TouchColor;
        //else
        //  MenuButton.TouchColor = Color.Lerp(Color.Black, SavedColor, 0.5f);

        //Tempo di durata effetto
        //ColorCounter--;
        //if (ColorCounter < 0)
        //{
        //  MenuButton.color = SavedColor;
        //  ColorCounter = 5;
        //  MenuButton.touched = false;
        //}
      }
    }

    public override void UpdateShowLastTake(GameTime gameTime)
    {
      foreach (var g in cachedGestures)
      {
        if (g.GestureType == GestureType.Tap)
        {
          gameState.Animations.Clear();
          renderState = RenderState.Input;
          //cachedGestures.Clear();
          //return;
        }
      }


      //if (renderState != RenderState.ShowLastTake)
      //  base.UpdateInput(gameTime);
    }


    public override void UpdateTurnStart(GameTime gameTime)
    {
      foreach (var g in cachedGestures)
      {
        switch (g.GestureType)
        {
          case GestureType.Tap:
            if (renderState == RenderState.TurnStart)
            {
              // Check if the button to start the turn was tapped
              var button = turnStartBtns[gameState.CurrentPlayerIndex];
              //var turnStartBtn = new Rectangle(button.X - (button.Width / 2), button.Y - (button.Height / 2), button.Width, button.Height);
              var turnStartBtn = new Rectangle(gameBounds.Center.X - (play.Bounds.Width / 2), gameBounds.Center.Y - (play.Bounds.Height / 2), play.Bounds.Width, play.Bounds.Height);
              if (turnStartBtn.Contains(g.Position.ToPoint(screen_transform)))
              {
                // Show the cards of the player
                var player = gameState.Players[gameState.CurrentPlayerIndex];
                for (int j = 0; j < player.Cards.Count; j++)
                {
                  var card = player.Cards[j];
                  if (card.ShowBack)
                  {
                    gameState.Animations.Add(new CardAnimation() { Card = card, AnimationType = AnimationType.ShowPlayerCards, AnimationFinished = false, Amount = 50, PlayerIndex = gameState.CurrentPlayerIndex });
                    gameState.MossaFatta = true;
                  }
                }
                renderState = RenderState.Input;
              }
            }
            break;
        }
      }
    }

    public override void Draw(GameTime gameTime)
    {
      base.Draw(gameTime);
    }

    public override void DrawUI(GameTime gameTime)
    {
      // Draw menu button
      spriteBatch.Draw(MenuButton.texture, MenuButton.bounds, null, MenuButton.color, 0, Vector2.Zero, SpriteEffects.None, 1.0f);
      spriteBatch.DrawString(MenuButton.spriteFont, MenuButton.message, new Vector2((float)MenuButton.bounds.Center.X, (float)MenuButton.bounds.Center.Y), MenuButton.textColor, 0, MenuButton.spriteFont.MeasureString(MenuButton.message) / 2, MenuButton.scale, SpriteEffects.None, 1.0f);

      // Draw button that shows last takes
      if (renderState == RenderState.Input)
        spriteBatch.Draw(showTakes, showLastTakeRect, null, Color.Yellow, 0.0f, Vector2.Zero, SpriteEffects.None, 1.0f);

      if (!Outro)
      {
        // Barra Interfaccia (Entrata Slide)
        //sprite_batch.Draw(barr, new Rectangle(0, -60 + intro, 800, 60), new XNAColor(200, 200, 200, 200));

        // Oscura la Schermata di Gioco
        //if (this.Enabled == false) spriteBatch.Draw(whitePx, Game.GraphicsDevice.Viewport.Bounds, new Color(0, 0, 0, 100));

        // Disegna il Nome del Giocatore
        //if (!board.Players.ElementAt(0).Name.Equals("default"))
        //{
        //  sprite_batch.DrawString(small_font, board.Players.ElementAt(0).Name, new Vector2(550, -53 + intro), XNAColor.Gray);
        //  sprite_batch.DrawString(small_font, board.Players.ElementAt(0).Name, new Vector2(551, -52 + intro), textColor);
        //}
        //else
        //{
        //  sprite_batch.DrawString(small_font, Locale.Strings.CreateProfHint.Replace("\\n", "\n"), new Vector2(550, -53 + intro), XNAColor.Gray, 0.0f, Vector2.Zero, 0.7f, SpriteEffects.None, 0.0f);
        //  sprite_batch.DrawString(small_font, Locale.Strings.CreateProfHint.Replace("\\n", "\n"), new Vector2(551, -53 + intro), textColor, 0.0f, Vector2.Zero, 0.7f, SpriteEffects.None, 0.0f);
        //}

        // Disegna fondino controllo audio
        //sprite_batch.Draw(box, new Rectangle(740, 480 - intro, 80, intro + 10), null, new XNAColor(200, 200, 200, 200), 0.0f, Vector2.Zero, SpriteEffects.None, 0.99f);

        // Visualizza titolo traccia audio
        //sprite_batch.Draw(Game.Content.Load<Texture2D>("white_pixel"), new Rectangle(songRectangle.Left - 38, songRectangle.Top - 3, songRectangle.Width + 76, songRectangle.Height + 26), XNAColor.BlanchedAlmond);
        //sprite_batch.Draw(Game.Content.Load<Texture2D>("white_pixel"), songRectangle, XNAColor.Black);
        //sprite_batch.DrawString(small_font, songName, new Vector2(songRectangle.Left + 3, songRectangle.Top), XNAColor.Gold);
      }
    }

    public override void DrawTakes(GameTime gameTime)
    {
      // Draw a grey curtain
      spriteBatch.Draw(whitePx, gameBounds, null, Color.Lerp(Color.Gray, Color.Transparent, 0.2f), 0.0f, Vector2.Zero, SpriteEffects.None, 0.7f);

      // Draw last take cards
      foreach (var player in gameState.Players)
      {
        if (player.Takes.Any())
        {
          var take = player.Takes.Last();
          foreach (var card in take.Cards)
            DrawCard(card);
        }
      }

      // Draw Pack Cards Num
      spriteBatch.DrawString(font, gameState.Pack.Cards.Count.ToString(), new Vector2(5, 450), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f);

      // Draw button
      spriteBatch.Draw(showTakes, showLastTakeRect, null, Color.White, 0.0f, Vector2.Zero, SpriteEffects.None, 1.0f);
    }

    public override void DrawTurnStart(GameTime gameTime)
    {
      // Draw a grey curtain
      spriteBatch.Draw(whitePx, gameBounds, null, Color.Lerp(Color.Gray, Color.Transparent, 0.2f), 0.0f, Vector2.Zero, SpriteEffects.None, 0.7f);

      var plArea = playerAreas[gameState.CurrentPlayerIndex];
      if (gameState.Players.ElementAt(gameState.CurrentPlayerIndex).AIType == AIType.Human)
        spriteBatch.Draw(play, new Rectangle(gameBounds.Center.X, gameBounds.Center.Y, play.Bounds.Width, play.Bounds.Height), null, gameState.Players[gameState.CurrentPlayerIndex].Color, plArea.cardsRotation, new Vector2(play.Bounds.Center.X, play.Bounds.Center.Y), SpriteEffects.None, 1.0f);
      //spriteBatch.Draw(play, turnStartBtns[gameState.CurrentPlayerIndex], null, Color.White, plArea.cardsRotation, new Vector2(play.Bounds.Center.X, play.Bounds.Center.Y), SpriteEffects.None, 1.0f);
    }



    public override event OnMenuPause OnMenuPause;
    public override event OnMatchExit OnMatchExit;
  }
}
